import axios from 'axios';
import { ElMessage } from 'element-plus' // 使用antd消息提示
import { getToken, clearToken } from './auth'; // 假设有token管理模块

// 创建axios实例

const http = axios.create({
  baseURL: import.meta.env.VITE_API_BASE_URL,
  timeout: 15000,
  headers: { 'Content-Type': 'application/json' }
});

// 请求队列
const pendingRequests = new Map();

// 生成请求标识
// 定义一个名为 generateReqKey 的函数，用于生成请求的唯一标识符
const generateReqKey = (config) => {
  // 返回一个由多个部分组成的字符串，这些部分通过 '&' 符号连接
  return [
    // config.method 表示请求的方法，如 GET、POST 等
    config.method,
    // config.url 表示请求的 URL 地址
    config.url,
    // JSON.stringify(config.params) 将请求的参数对象转换为 JSON 字符串
    JSON.stringify(config.params),
    // JSON.stringify(config.data) 将请求的数据对象转换为 JSON 字符串
    JSON.stringify(config.data)
  ].join('&');
};

// 添加请求到队列
// 定义一个函数 addPendingRequest，用于添加待处理的请求
const addPendingRequest = (config) => {
  // 调用 generateReqKey 函数生成请求的唯一标识符
  const requestKey = generateReqKey(config);
  // 为 config 对象设置 cancelToken 属性，如果它不存在则创建一个新的 axios.CancelToken 实例
  config.cancelToken = config.cancelToken || new axios.CancelToken(cancel => {
    // 检查 pendingRequests 中是否已经存在该请求标识符
    if (!pendingRequests.has(requestKey)) {
      // 如果不存在，则将请求标识符和取消函数存储到 pendingRequests 中
      pendingRequests.set(requestKey, cancel);
    }
  });
};

// 移除请求
// 定义一个名为 removePendingRequest 的函数，用于移除待处理的请求
const removePendingRequest = (config) => {
  // 调用 generateReqKey 函数生成请求的唯一标识符
  const requestKey = generateReqKey(config);
  // 检查 pendingRequests 集合中是否包含当前请求的唯一标识符
  if (pendingRequests.has(requestKey)) {
    // 如果存在，则获取对应的取消请求的函数
    const cancel = pendingRequests.get(requestKey);
    // 调用取消请求的函数，并传入请求的唯一标识符
    cancel(requestKey);
    // 从 pendingRequests 集合中删除该请求的唯一标识符
    pendingRequests.delete(requestKey);
  }
};

// 请求拦截器
http.interceptors.request.use(
  (config) => {
    // 取消重复请求
    removePendingRequest(config);
    addPendingRequest(config);
    
    // 自动添加token
    const token = getToken();
    if (token && !config.headers.Authorization) {
      config.headers.Authorization = `Bearer ${token}`;
    }
    
    // 全局loading控制（需配合状态管理）
    // store.dispatch(showGlobalLoading());
    
    return config;
  },
  (error) => {
    return Promise.reject(error);
  }
);

// 响应拦截器
http.interceptors.response.use(
  (response) => {
    // 移除请求队列
    removePendingRequest(response.config);
    
    // 关闭loading
    // store.dispatch(hideGlobalLoading());
    
    // 处理业务状态码（根据后端协议调整）
    const { code, data } = response.data;
    if (code !== 200) {
      if (code === 401) {
        // token过期处理
        clearToken();
        window.location.href = '/login';
      }
      ElMessage.error(data.message || '操作失败');
      return Promise.reject(new Error(data.message ));
    }
    
    return response.data;
  },
  (error) => {
    // 关闭loading
    // store.dispatch(hideGlobalLoading());
    
    // 处理取消的请求
    if (axios.isCancel(error)) {
      console.log('请求被取消:', error.message);
      return Promise.reject(error);
    }
    
    // 错误处理
    let errorMessage = '请求失败';
    if (error.response) {
      switch (error.response.status) {
        case 401:
          errorMessage = '登录已过期，请重新登录';
          clearToken();
          window.location.href = '/login';
          break;
        case 403:
          errorMessage = '没有操作权限';
          break;
        case 500:
          errorMessage = '服务器异常';
          break;
      }
    } else if (error.message.includes('timeout')) {
      errorMessage = '请求超时';
    } else if (error.message.includes('Network Error')) {
      errorMessage = '网络连接失败';
    }
    
  ElMessage.error(errorMessage);
    return Promise.reject(error);
  }
);

// 封装常用方法（支持自动重试）
export const request = {
  get: (url, params, config) => http.get(url, { params, ...config }),
  post: (url, data, config) => http.post(url, data, config),
  put: (url, data, config) => http.put(url, data, config),
  patch: (url, data, config) => http.patch(url, data, config),
  delete: (url, params, config) => http.delete(url, { params, ...config }),
  upload: (url, file, config) => {
    const formData = new FormData();
    formData.append('file', file);
    return http.post(url, formData, {
      headers: { 'Content-Type': 'multipart/form-data' },
      ...config
    });
  },
  // 带自动重试的请求
  retry: async (fn, retries = 3, delay = 1000) => {
    try {
      return await fn();
    } catch (error) {
      return retries > 1 
        ? new Promise(resolve => 
            setTimeout(() => resolve(request.retry(fn, retries - 1, delay)), delay)
          )
        : Promise.reject(error);
    }
  }
};

// 自定义Hook封装
// 导出一个名为 useHttp 的常量，它是一个函数
export const useHttp = () => {
  // 可以在此集成全局loading状态管理
  return {
    ...request,
    // 扩展其他方法...
  };
};
